package com.saceem.imagenes.logica;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.URL;
import java.net.URLConnection;

import org.apache.log4j.Logger;

import javax.ejb.EJB;
import javax.ejb.EJBTransactionRolledbackException;
import javax.ejb.Stateless;
import javax.imageio.ImageIO;
import javax.persistence.PersistenceException;
import javax.validation.ConstraintViolationException;

import com.saceem.beans.Imagenes;
import com.saceem.beans.keys.ImagenesPK;
import com.saceem.imagenes.test.FuncionesImagenes;
import com.saceem.imagenes.test.FuncionesImagenesException;
import com.saceem.imagenes.test.LectorCodigosDeBarra;
import com.saceem.imagenes.test.LectorCodigosDeBarraException;
import com.saceem.imagenes.test.PropiedadesProcesadorFacturas;
import com.saceem.utils.mail.MailBean;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;

@Stateless
public class ProcesadorFacturas implements IProcesadorFactruas {
	private final static Logger log = Logger.getLogger(ProcesadorFacturas.class
			.getName());

	@EJB
	ImageManager imgManager;

	@EJB
	MailBean mailBean;

	@EJB
	FuncionesImagenes fImagenes;

	@EJB
	LectorCodigosDeBarra lcb;

	private String mailTo;

	/**
	 * @return the mailTo
	 */
	public String getMailTo() {
		return mailTo;
	}

	/**
	 * @param mailTo
	 *            the mailTo to set
	 */
	public void setMailTo(String mailTo) {
		this.mailTo = mailTo;
	}

	@Override
	public void procesar() {

		int cnt = 0;
		int cntZf = 0;

		try {
			PropiedadesProcesadorFacturas props = PropiedadesProcesadorFacturas
					.getInstance();

			// TODO Modificar esto para que cuando no se encuentren imagenes.
			log.info("#######################################");
			// log.info(props.getRutaOrigen());

			setMailTo(props.getDestinatarioCorreo());

			String[] archivos = obtenerImagenesAProcesar(props.getRutaOrigen());
			log.info("Cantidad de imagenes encontradas : " + archivos.length);

			for (int i = 0; i < archivos.length; i++) {
				try {
					log.info("  Procesando Archivo: " + archivos[i]);
					String nombre = lcb.leerCodigoDeBarra(props.getRutaOrigen()
							+ "/" + archivos[i]);

					String emp = nombre.substring(0, 4);

					if (emp.endsWith("1")) {
						cnt++;
					} else {
						cntZf++;
					}

					log.info("  El codigo de barra es: " + nombre);

					// TODO Aca evaluar si en lugar de enviarlo a una carpeta,
					// mandarlo directo a la base.
					moverImagenACarpeta(props.getRutaOrigen(), archivos[i],
							props.getRutaDestino() + "/" + emp, nombre + ".gif");
				} catch (LectorCodigosDeBarraException lce) {
					log.info("  Error al procesar la imagen " + archivos[i]);
					lce.printStackTrace();

					// No se pudo leer, se copia a carpeta de error y se
					// manda mail.
					moverImagenACarpeta(props.getRutaOrigen(), archivos[i],
							props.getRutaError(), archivos[i]);

					// Mandar mail.
					mandarMailErrorReconocimiento(props.getRutaError() + "/"
							+ archivos[i], lce.getMessage(), getMailTo());
				}
			}

			if (archivos.length > 0) {
				if (cnt != 0) {
					salvarImagen(props.getRutaDestino() + "/0101/");
				} else if (cntZf != 0) {
					salvarImagen(props.getRutaDestino() + "/0106/");
				}
			}
			log.info("Fin proceso de Imagenes");
			log.info("#######################################");

		} catch (Throwable t) {
			// log.error("Erro no controlado, verifique tener instalado jai");
			log.error(t.getMessage());

			t.printStackTrace();
			// MailManager
			// .enviarMail(
			// "Error procesando imagenes - Erro no controlado, verifique tener instalado jai",
			// t.getMessage());
		} finally {
			cnt = 0;
			cntZf = 0;
		}

		// try {
		// PropiedadesProcesadorFacturas props = PropiedadesProcesadorFacturas
		// .getInstance();
		// log.info("Durmiendo : " + props.getIntervalo()
		// + " segundos.");
		// Thread.sleep(props.getIntervalo() * 1000);
		// } catch (InterruptedException ie) {
		// ie.printStackTrace();
		// }
	}

	private static String[] obtenerImagenesAProcesar(String ruta) {
		// log.info("obteniendo imagenes de : " + ruta);
		FilenameFilter filter = new FilenameFilter() {
			public boolean accept(File dir, String name) {
				return name.toLowerCase().endsWith(".jpg");
			}
		};
		File dir = new File(ruta);
		return dir.list(filter);
	}

	private static String[] obtenerImagenesAguardar(String ruta) {
		// log.info("obteniendo imagenes a guardar");
		FilenameFilter filter = new FilenameFilter() {
			public boolean accept(File dir, String name) {
				return name.toLowerCase().endsWith(".gif");
			}
		};
		File dir = new File(ruta);
		return dir.list(filter);
	}

	@SuppressWarnings("static-access")
	private void moverImagenACarpeta(String rutaOrigen, String archivo,
			String rutaDestino, String nombre) {
		log.info("	Moviendo imagenes");
		try {
			File f = new File(rutaDestino);
			if (!f.exists()) {
				log.info("	Se creado el directorio : " + rutaDestino);
				f.mkdir();
			}

			// log.info("rutaOrigen :" + rutaOrigen + ".");
			// log.info("archivo :" + archivo + ".");
			// log.info("rutaDestino :" + rutaDestino + ".");
			// log.info("nombre :" + nombre + ".");

			fImagenes.moverImagen(rutaOrigen + "/" + archivo, rutaDestino + "/"
					+ nombre);

		} catch (Throwable t) {
			t.printStackTrace();
		}
	}

	@SuppressWarnings("static-access")
	private void mandarMailErrorReconocimiento(String archivo, String error,
			String mailTo) {
		File f = new File(archivo);

		// MailMessage msg = new MailMessage();
		// msg.setAddressTo("nbordenave@saceem.com");
		// msg.setAddressCc("nborde@gmail.com");
		// msg.setEmpresa("010");
		// msg.setError(error);
		// msg.setF(f);
		//
		// try {
		// mNotificationUtils.sendJMSMessageToNotificationQueue(msg);
		// } catch (JMSException e) {
		// // TODO Auto-generated catch block
		// e.printStackTrace();
		// }
		// escaneofactprov@saceem.com.uy

		mailTo = "escaneofactprov@saceem.com.uy";

		mailBean.sendMailWithAtt(mailTo, null, f, error, "010");

		try {
			fImagenes.eliminarImagen(f.getAbsolutePath());
		} catch (FuncionesImagenesException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@SuppressWarnings("static-access")
	private void salvarImagen(String rutaArchivos) {

		BufferedImage img = null;
		log.info("#### #### ####  Guardando imagenes #### #### #### ####");
		String[] archivos = obtenerImagenesAguardar(rutaArchivos);
		log.info("Cantidad de imagenes a guardar : " + archivos.length);

		for (int i = 0; i < archivos.length; i++) {

			File f = new File(rutaArchivos + "/" + archivos[i]);
			try {
				img = ImageIO.read(f);

				ByteArrayOutputStream baos = new ByteArrayOutputStream(1000);
				ByteArrayOutputStream baosAux = new ByteArrayOutputStream(1000);

				String nombre = f.getName();
				String formato = nombre.substring((nombre.length() - 3));

				ImageIO.write(img, formato, baos);
				baos.flush();

				String base64String = Base64.encode(baos.toByteArray());
				baos.close();

				// Con esto lo que hago es convertir el archivo a gif para
				// guardarlo.
				byte[] bytearray = Base64.decode(base64String);

				nombre = nombre.replace(formato, "gif");

				BufferedImage imag = ImageIO.read(new ByteArrayInputStream(
						bytearray));
				ImageIO.write(imag, "gif", baosAux);
				baosAux.flush();
				baos.close();

				String empresa = nombre.substring(0, 3);
				Long codigo = Long.valueOf((String) nombre.subSequence(0,
						nombre.length() - 4));

				Imagenes imagen = new Imagenes(nombre, empresa);
				ImagenesPK pKey = new ImagenesPK(nombre, empresa);
				imagen.setpKey(pKey);

				imagen.setCodigo(codigo);

				try {
					imgManager.salvarImagen(imagen, bytearray);

					if (!f.delete()) {
						log.info("No se borro la imagen");
					}

				} catch (ConstraintViolationException e) {
					// TODO Aca ver que hacer con este error.
					// log.error("Aca tengo que ver de manejar puntualmente esta exception: ConstraintViolationException");
					log.error(e);
				} catch (PersistenceException e) {
					// log.error("Aca tengo que ver de manejar puntualmente esta exception: PersistenceException");
					log.error(e);
				} catch (EJBTransactionRolledbackException e) {
					// log.error("Aca tengo que ver de manejar puntualmente esta exception: EJBTransactionRolledbackException");

					if (e.getLocalizedMessage().contains(
							"ConstraintViolationException")) {
						// log.info("El codigo de barras "
						// + codigo
						// +
						// " ya existe, pegue un codigo nuevo y repita el proceso.");
						// Mandar mail.
						mandarMailErrorReconocimiento(
								f.getAbsolutePath(),
								"El codigo de barras "
										+ codigo
										+ " ya existe, pegue un codigo nuevo y repita el proceso. "
										+ e.getLocalizedMessage(), getMailTo());
						if (!f.delete()) {
							log.info("No se borro la imagen");
						}
					}

				} catch (Exception e) {
					log.error(e);
					// e.printStackTrace();
				}

			} catch (IOException e) {
				log.error(e.getMessage(), e.getCause());
				e.printStackTrace();
			}

		}

		log.info("#### #### #### #### #### #### #### #### #### #### ####");

	}

	private static void invocarServlet() {
		String name = "escaner";
		String empresa = "010";
		StringBuffer path = new StringBuffer();
		path.append("http://192.168.1.216:8080/ReportesTotvs/SalvarImagen?codigo=");
		path.append(name);
		path.append("&emp=");
		path.append(empresa);
		try {
			URL url = new URL(path.toString());
			URLConnection conn = url.openConnection();

			// Prepare for both input and output
			conn.setDoInput(true);
			conn.setDoOutput(true);

			// Turn off caching
			conn.setUseCaches(false);

			// Set the content type to be java-internal/classname
			conn.setRequestProperty("Content-type",
					"application/x-java-serialized-object");

			// Write the object as post data
			ObjectOutputStream out;
			out = new ObjectOutputStream(conn.getOutputStream());
			out.flush();
			out.close();

			conn.getInputStream();
			log.info("Guardo.");

		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	public static void main(String[] args) {
		String nombre = "01010000899.gif";
		String empresa = nombre.substring(0, 3);
		String codigo = (String) nombre.subSequence(0, nombre.length() - 4);

		System.out.println(empresa);
		System.out.println(codigo);

	}
}
